package com.hxh.myAop;

import com.hxh.entity.Project;
import com.hxh.entity.ProjectDatasource;
import com.hxh.entity.input.ProjectInput;
import com.hxh.service.ProjectConfigRecordService;
import com.hxh.service.ProjectDatasourceService;
import com.hxh.service.ProjectService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

import static com.hxh.util.Common.hasPropertyChanged;

/**
 * @author HXH
 * @description: 记录项目版本变更，记录需要操作的类型，如重启、重新生成表代码、重新初始化项目
 */
@Aspect
@Component
@Slf4j
public class ProjectConfigRecordDatabaseAspect {

    @Autowired
    private ProjectConfigRecordService projectConfigRecordService;
    @Autowired
    private ProjectService projectService;
    @Autowired
    private ProjectDatasourceService projectDatasourceService;


    /*************************数据源中数据表变更 标志处理 start********************************/
//    数据库信息发生变更，需要重新初始化前后端代码
//    拦截方法：com.hxh.service.ProjectDatasourceService.update
    @Around("execution(* com.hxh.service.ProjectDatasourceService.update(com.hxh.entity.ProjectDatasource)) && args(pojo)")
    public Object aroundUpdateProjectDatasource(ProceedingJoinPoint joinPoint, ProjectDatasource pojo) throws Throwable {
        // 获取旧数据
        ProjectDatasource oldOne = null;
        if (pojo.getId() != null) {
            oldOne = projectDatasourceService.selectById(pojo.getId());
        }

        // 执行原方法
        Object result = joinPoint.proceed();

        // 判断是否更新成功
        boolean success = result instanceof Boolean && (Boolean) result;

        boolean hasChange = hasPropertyChanged(oldOne, pojo, "mysqlDatabaseName", "mysqlDriver", "mysqlConnectUrl", "mysqlUsername", "mysqlPassword");
        if (success && hasChange) {
            // 判断是否需要触发重建逻辑：比如数据库名变更
            processDataSourceChange(pojo.getId());
        }
        return result;
    }

    private void processDataSourceChange(Integer datasourceId) {
        ProjectInput projectInput = new ProjectInput();
        projectInput.setDatasourceId(datasourceId);
        List<Project> projects = projectService.select(projectInput);
        if (projects.isEmpty()) {
            return;
        }
        List<Integer> projectIdList = projects.stream().map(Project::getId).collect(Collectors.toList());

        projectIdList.forEach(projectId -> {
            projectConfigRecordService.initSystem(projectId, "back,front");
            projectConfigRecordService.addLocalVersion(projectId);
        });
    }

    /*************************数据源中数据表变更 标志处理 end********************************/

}
